$git_pr_api = "https://api.github.com/repos/%s/SalesforceMobileSDK-iOS/pulls/%s/files"
$schemes = ['SalesforceSDKCommon', 'SalesforceAnalytics', 'SalesforceSDKCore', 'SmartStore', 'MobileSync']
ENV['DEVICE'] = 'iPhone 11' unless ENV.has_key?('DEVICE')
ENV['IOS_VERSION'] = '13.7' unless ENV.has_key?('IOS_VERSION')

lane :PR do |options|
  lib_to_test = options[:lib]
  Dir.chdir('../')
  schemes = Set.new

  if (ENV.has_key?('NIGHTLY_TEST') and ENV['NIGHTLY_TEST'] == 'true')
    UI.important "Nightly, skipping modified check."
    test_scheme(lib_to_test)
  else
    # Check if this is a PR.
    # Rebuilds of PR's don't have the CIRCLE_PULL_REQUEST key, so check the branch instead.
    if ENV.has_key?('CIRCLE_BRANCH') && ENV['CIRCLE_BRANCH'].include?('pull/')
      # No PR Number indicates that this PR is running in a CircleCI env linked to a fork, so force the url to forcedotcom project.
      if ENV.has_key?('CIRCLE_PR_NUMBER')
        pr_files_api = $git_pr_api % [ENV['CIRCLE_PROJECT_USERNAME'], ENV['CIRCLE_PR_NUMBER']]
      else
        pr_files_api = $git_pr_api % ['forcedotcom', ENV['CIRCLE_BRANCH'].split('/').last]
      end
      pull_files = `#{"curl %s" % [pr_files_api]}`
    else
      UI.error 'Not a PR on CircleCI, stopping stop execution now.'
      `circleci step halt`
      next
    end

    # Determine which libs have been modified
    pr_files = JSON.parse(pull_files)
    for pr_file in pr_files
      path = pr_file['filename']
      for scheme in $schemes
        if path.include? scheme
          schemes.add(scheme)
        end
      end
    end
    UI.important "Schemes to test: " + schemes.to_a().join(',')

    if schemes.include? lib_to_test
      test_scheme(lib_to_test)
    else
      UI.important "Lib #{lib_to_test} not modified by this PR, no need to test."
      `circleci step halt`
    end
  end
end

lane :LCL do
  Dir.chdir('../')
  index = 1
  puts 'Select scheme: '
  for scheme in $schemes
    puts index.to_s + ': ' + scheme
    index = index + 1
  end

  print 'Just enter a number or name: '
  selection = STDIN.gets.strip

  if $schemes.include? selection
    test_scheme(selection)
  # Not the best error handling, but sufficient for catching typos
  elsif selection.to_i > 0 and selection.to_i <= $schemes.count
    test_scheme($schemes[selection.to_i - 1])
  else
    UI.user_error!('Invalid test selection.')
  end
end

lane :CI do
  Dir.chdir('../')
  test_scheme('UnitTests')
end

def test_scheme(scheme)
  analyze_scheme(scheme)

  device = ENV['DEVICE'].gsub(' ', '-')
  ios = ENV['IOS_VERSION'].gsub('.', '-')
  system('xcrun simctl delete test_device') or true
  sim_id = `xcrun simctl create test_device com.apple.CoreSimulator.SimDeviceType.#{device} com.apple.CoreSimulator.SimRuntime.iOS-#{ios}`.delete("\n")
  destination = "test_device (" + `instruments -s devices | grep test_device | awk -F"[()]" '{print $2}'`.delete("\n") + ")"
  begin
    scan(
        workspace: 'SalesforceMobileSDK.xcworkspace',
        scheme: scheme,
        device: destination,
        output_directory: 'test_output',
        output_types: 'html,junit',
        code_coverage: true,
        skip_build: true
    )
  ensure
    system("mv ../test_output/report.html ../test_output/#{scheme}_results.html")
  end
end

def analyze_scheme(scheme)
    begin
      xcodebuild(
          xcargs: 'CLANG_ANALYZER_OUTPUT=plist-html CLANG_ANALYZER_OUTPUT_DIR=./clangReport RUN_CLANG_STATIC_ANALYZER=YES ARCHS=x86_64',
          workspace: 'SalesforceMobileSDK.xcworkspace',
          scheme: scheme,
          sdk: 'iphonesimulator',
          )
    ensure
      #move clangReports to one folder
      system('mkdir -p ../clangReport/StaticAnalyzer')
      system('mv ../libs/SalesforceSDKCommon/clangReport/StaticAnalyzer/SalesforceSDKCommon ../clangReport/StaticAnalyzer/')
      system('mv ../libs/SalesforceAnalytics/clangReport/StaticAnalyzer/SalesforceAnalytics ../clangReport/StaticAnalyzer/')
      system('mv ../libs/SalesforceSDKCore/clangReport/StaticAnalyzer/SalesforceSDKCore ../clangReport/StaticAnalyzer/')
      system('mv ../libs/SmartStore/clangReport/StaticAnalyzer/SmartStore ../clangReport/StaticAnalyzer/')
      system('mv ../libs/MobileSync/clangReport/StaticAnalyzer/MobileSync ../clangReport/StaticAnalyzer/')
    end
end
